package cz.data.common.database.dialect;

import cz.data.common.support.db.core.DbColumn;
import cz.data.common.support.db.core.DbTable;
import org.apache.commons.lang3.StringUtils;
import org.springframework.jdbc.core.RowMapper;

import java.sql.ResultSet;

public class VerticaDialect extends AbstractDbDialect {
    @Override
    public String tableNames(String dbName, String schema) {
        String command = "SELECT t.table_name " +
                "FROM (select table_name, table_id, table_schema from tables union all select table_name, table_id, table_schema from views) t";
        if (StringUtils.isNotBlank(schema)) {
            command = command + " WHERE t.table_schema = '" + schema + "'";
        }
        return command;
    }

    @Override
    public String columnNames(String dbName, String schemaName, String tableName) {
        if (StringUtils.isBlank(schemaName)) {
            schemaName = "public";
        }
        //TODO v_开头表视为是图表
        if (StringUtils.startsWithIgnoreCase(tableName, "v_")) {
            return "SELECT c.column_name " +
                    "FROM VIEW_COLUMNS c WHERE c.table_schema = '" + schemaName + "' AND c.table_name = '" + tableName + "'";
        } else {
            return "SELECT c.column_name " +
                    "FROM COLUMNS c WHERE c.table_schema = '" + schemaName + "' AND c.table_name = '" + tableName + "'";
        }
    }

    @Override
    public String tables(String dbname, String schemaName) {
        String command = "SELECT t.table_name, t.table_type," +
                "(select \"comment\" from comments where object_id = t.table_id AND object_type in ('VIEW', 'TABLE')) as tableComment " +
                "FROM (select table_name, table_id, table_schema, '1' AS table_type from tables " +
                "union all select table_name, table_id, table_schema, '2' AS table_type from views) t";
        if (StringUtils.isNotBlank(schemaName)) {
            command = command + " WHERE t.table_schema = '" + schemaName + "'";
        }
        return command;
    }

    @Override
    public RowMapper<DbTable> tableMapper() {
        return (ResultSet rs, int rowNum) -> {
            DbTable table = new DbTable();
            table.setTableName(rs.getString("table_name"));
            table.setTableComment(rs.getString("tableComment"));
            String tableType = rs.getString("table_type");
            if (StringUtils.isNotBlank(tableType)) {
                table.setTableType(tableType);
            }
            return table;
        };
    }

    @Override
    public String columns(String dbname, String schemaName, String tableName) {
        if (StringUtils.isBlank(schemaName)) {
            schemaName = "public";
        }
        //TODO v_开头表视为是图表
        if (StringUtils.startsWithIgnoreCase(tableName, "v_")) {
            return "SELECT c.column_name, c.data_type, c.data_type_length, c.numeric_precision, c.numeric_scale, NULL AS is_nullable, NULL AS column_default, c.ordinal_position, " +
                    "(SELECT \"comment\" FROM comments WHERE object_id = c.table_id AND child_object = c.column_name AND object_type = 'COLUMN') as columnComment, NULL AS cloKey " +
                    "FROM VIEW_COLUMNS c WHERE c.table_schema = '" + schemaName + "' AND c.table_name = '" + tableName + "'";
        } else {
            return "SELECT c.column_name, c.data_type, c.data_type_length, c.numeric_precision, c.numeric_scale, c.is_nullable, c.column_default, c.ordinal_position, " +
                    "(SELECT \"comment\" FROM comments WHERE object_id = c.table_id AND child_object = c.column_name AND object_type = 'COLUMN') as columnComment, " +
                    "(SELECT constraint_type FROM CONSTRAINT_COLUMNS WHERE table_id = c.table_id AND column_name = c.column_name and constraint_type = 'p') cloKey " +
                    "FROM COLUMNS c WHERE c.table_schema = '" + schemaName + "' AND c.table_name = '" + tableName + "'";
        }
    }

    @Override
    public RowMapper<DbColumn> columnMapper() {
        return (ResultSet rs, int rowNum) -> {
            DbColumn entity = new DbColumn();
            entity.setColName(rs.getString("column_name"));
            String dataType = rs.getString("data_type");
            entity.setDataType(formatDataType(dataType));
            entity.setDataLength(rs.getString("data_type_length"));
            entity.setDataPrecision(rs.getString("numeric_precision"));
            entity.setDataScale(rs.getString("numeric_scale"));
            entity.setColKey("p".equals(rs.getString("cloKey")));
            entity.setNullable(rs.getBoolean("is_nullable"));
            entity.setColPosition(rs.getInt("ordinal_position"));
            entity.setDataDefault(rs.getString("column_default"));
            entity.setColComment(rs.getString("columnComment"));
            return entity;
        };
    }

    @Override
    public String buildPaginationSql(String originalSql, long offset, long count) {
        StringBuilder sqlBuilder = new StringBuilder(originalSql);
        sqlBuilder.append(" LIMIT ").append(count).append(" offset ").append(offset);
        return sqlBuilder.toString();
    }


}
